feat(mini.files): make file system actions LSP aware#2340
feat(mini.files): make file system actions LSP aware#2340TheLeoP wants to merge 14 commits intonvim-mini:mainfrom
Conversation
|
To test the PR using with the following content -- main.lua
local something = require("something").something
something()
-- something.lua
local M = {}
M.something = function()
print("something")
end
return Myou can then |
|
The tests errors seem to go away if I comment out Line 2898 in 134f9dd and Line 2911 in 134f9dd But I'm not sure why. In particular, the problematic lines seem to be Line 2754 in 134f9dd and Line 2802 in 134f9dd changing them to local clients = {}seems to also make the test pass. Are these tests specially time sensitive? I can't think of another reason of why they would be failing |
echasnovski
left a comment
There was a problem hiding this comment.
Thanks for the PR!
There are at least two good things: the LSP complexity seems to be understood and managed (the worst part for me :) ) and there is a room for making it more concise.
I don't think so. Probably, some logic has been broken. Didn't read too much into the code.
Restricting this functionality to only Neovim<0.11 is fine.
I am okay with these checks for I'll also take a look into how to better handle the "close on lost focus" in 'mini.files'. It will probably have to be "don't close if inside non-normal buffer in a floating window" type of exception. |
Okay, I've looked into this. Going the "don't close explorer if in floating window" goes against some of the use cases that originally prompted the tracking of lost focus. Like "I want to I think the best compromise here would be to temporarily adjust Something like this (as of the current state of this PR) seems to work: diff --git a/lua/mini/files.lua b/lua/mini/files.lua
index 304e895f..fce1bbb7 100644
--- a/lua/mini/files.lua
+++ b/lua/mini/files.lua
@@ -1540,7 +1540,7 @@ end
H.explorer_track_lost_focus = function()
local track = vim.schedule_wrap(function()
local ft = vim.bo.filetype
- if ft == 'minifiles' or ft == 'minifiles-help' then return end
+ if H.skip_track_lost_focus or ft == 'minifiles' or ft == 'minifiles-help' then return end
local cur_win_id = vim.api.nvim_get_current_win()
MiniFiles.close()
pcall(vim.api.nvim_set_current_win, cur_win_id)
@@ -2753,6 +2753,15 @@ H.lsp_will_fs_do = function(action, params)
local full_method = 'workspace/' .. method .. 'Files'
local clients = vim.lsp.get_clients({ method = full_method })
+ local ui_select_orig = vim.ui.select
+ vim.ui.select = function(items, opts, on_choice)
+ H.skip_track_lost_focus = MiniFiles.get_explorer_state() ~= nil
+ ui_select_orig(items, opts, function(...)
+ H.skip_track_lost_focus, vim.ui.select = nil, ui_select_orig
+ on_choice(...)
+ end)
+ end
+
-- TODO(TheLeoP): configurable timeout
local timeout = 1000
for _, client in ipairs(clients) doOne thing to extra consider is whether there will be any side effects if Thinking about it more, maybe it is a good idea to have this kind of mock in general for the whole duration of the explorer. Will also work nicely with something like 'mini.snippets' (which can use |
Yeah, ignoring tracking lost focus while I tried it with this PR and:
|
|
Thanks for your feedback! I'll be a bit busy today and tomorrow, so I'll address your comments and I'll keep working on this PR on Sunday |
Soo... I spent some time investigating in the hopes of opening an issue in neovim/neovim to drop the
Repro steps for what I did:
|
d6f5b42 to
18ca59f
Compare
|
The bulk LSP request/notifications should be working now. I left them on separated commits to make reviewing a bit easier. Let me know if you have any more feedback regarding the implementation. After that is done, I'll focus on creating some tests. What would be your preference for testing this? My guess is that it would be to mock a language server. I can take a look at |
echasnovski
left a comment
There was a problem hiding this comment.
This is visibly better now, thanks! Added the next round of review.
This should now work on the latest |
|
I just tested the latest changes on |
|
To spare both of us the back and forth about mine vague "make less nesting" suggestion, I've pushed what I think is a reasonable improvement (4b300bc). It did increase line count by 12 lines, but this is probably due to comments, new robustness checks, and performance improvements (mostly by avoiding doing things when they are not needed). This should work okay now. Please double check the new code. If you notice an incorrect behavior, please point that out. After that - squash all commits before it. Now the less fun part - tests. Yes, I'd like this to be done by an explicit new mocked LSP server (there are 'tests/mock-lsp' examples for reference). It essentially should test:
|
|
For the
Also, for the tests with multiple LSP servers attached, you want them to be different servers that react to the |
|
I still have to implement the tests for the For the failing tests, I need to regenerate the snapshot and update the expected highlight groups, right? Also, is the I also caught an error with my previous assumptions regarding |
Whatever you think will cover real world usage better without accounting for rare cases that are not required by the spec. My guess would be that
If they are the result of the adding new entries to 'tests/dir-files' (which they indeed look like), then yeah.
As this is a file that is used within 'mini.files' tests, then it should be inside a 'tests/dir-files' directory. Beyond that it is on "whatever feels right" basis. I'd put this in the 'tests/dir-files/lsp-files' directory.
Whatever reasonably covers the "there are multiple LSP clients attached to the buffer" cases. Maybe a separate test case that has several servers attached, each with different capabilities? Like to test that if the server doesn't support a method, then there is no request done for it. |
39b2854 to
de203c2
Compare
Details: - Perform filter when converting diffs into LSP file actions. - Construct a single filter function instead of several ones. - Do not use `fs_get_type()` inside a filter for `matches` since the file/directory may not exist on disk. Instead rely on the convention that if file path ends with '/' in the diff - it is a directory. - Do not use `vim.iter` in favor of explicit loops.
|
It took me longer than I expected, but the tests cover a bunch more use cases now. So, I marked the PR as ready for review. I even ended up opening neovim/neovim#39099 while looking into how to send server to client requests from an in-memory LSP :p. Sorry for all the back and forth, btw. |
Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
|
I'm not sure why the tests on ubuntu with Neovim I'm also not sure why Windows is not triggering the |
Details: - Inside of multiline strings should have one indent step bigger than parent code that uses them. - Prefer to extract parts of nested data in the separate variable if it reduces number of lines and nesting. - Prefer key notation as described in `:h key-notation`. I.e. `<Esc>` and not `<esc>`. - Prefer emulating file manipulation by typing keys and not with `set_lines()`. Doesn't matter much, it is just what is mostly used in most file manipulation tests.
echasnovski
left a comment
There was a problem hiding this comment.
Overall tests look okay. I've pushed a commit with formatting and small code organization tweaks (trying to keep lines of code as small as reasonably possible).
I am still thinking about the best way to have this configurable. Do you think something like config.options.lsp_integration = true would be enough? Or should it be full-blown config.lsp = { enable = true, timeout = 1000 } (as in 'oil.nvim')?
After addressing this review comments, there is a documentation left. I am thinking:
- A small note at the top in the
Features:list. This should also be mirrored in the module's README. - A slightly more detailed note in the
MiniFiles-manipulationsection.
| return function(params) | ||
| table.insert(_G.lsp_requests, method) | ||
| table.insert(_G.request_params, params) | ||
| local path = vim.fn.fnamemodify('tests/dir-files/lsp-files/main.lua', ':p') |
There was a problem hiding this comment.
The idea of separate LSP mocks is that they should not depend on module specific test files. Can this be be generalized (like by using params)?
There was a problem hiding this comment.
A global variable could be used for configuring this. If params is used for this, it would mean executing an edit on the created/renamed file. It would still be necessary to use something different for deleted files, though
There was a problem hiding this comment.
Whatever makes it not assume that it runs in a 'mini.files' test in the most concise way.
No need to apologize. That the nature of the PR review and, if anything, it should be me who needs to apologize :)
Does the feature even work on Neovim 0.10 or is it only test? If not, I am fine with only enabling this on Neovim>=0.11 (i.e.
Sorry, I have no clue either. Maybe |
I prefer the first option ( |
|
After that last change the tests at least seem to be running on |
Details: - Make sure that generated documentation is not more than 78 characters wide. - Use `~` suffix for help headers. - Make more concise in features. - Mention specific LSP methods for users to be able to tell whether a server supports it.
Details:
- Create a helper once during `require('mini.files')`. More aligned with
how other modules do this and better performance (doesn't really
matter here, but still).
- Use `return` for Neovim<=0.11. There are still errors, but resolving
them might require updating the mock.
|
I've pushed some tweaks to the latest changes. Including a change in how client is requested on Neovim<0.11. Tests still fail (differently), but my guess is that this needs adjustments in mocks. I also removed the
Whether it needs to be future proof is the whole point :) Let's make it more concise then: The relevant section in 'MAINTAINING.md' will be a helpful checklist here. |
Addresses #2215
This is a proof of concept to test the idea of including this kind of LSP support inside of mini.files. It may not be merged at all or it may help to add new autocmds to allow users/other plugins to implement this themselves.
A few things to take into account
H.fs_do.deletehad to be changed to allow checkingsuccessa single time before triggeringdidDeleteFilenotifications (actually, it seems like I broke something)timeoutforclient:request_syncis harcodedvim.glob.to_lpeghas a bug prior to 0.11 that requires manually sorting items inside brackets as a workaround,client:request_sync/client:notifyare not methods prior to 0.11, etc)libuvdoes not offer an abstraction on top of it. Maybefs_statrelated function would work on Windows with the same semantics, I haven't tested it yet)